#ifndef __QTCH_SESSION_DATA_H__
#define __QTCH_SESSION_DATA_H__

#include <string>
#include <memory>
#include <unordered_map>
#include <boost/any.hpp>
#include <vector>
#include "qtch/mutex.h"
#include "qtch/singleton.h"



namespace qtch {
namespace http{


class SessionData {
public:
    typedef std::shared_ptr<SessionData> ptr;
    typedef RWMutex RWMutexType;

    SessionData();

    template<class T>
    void setData(const std::string& key,const T& v){
        RWMutexType::WriteLock lock(m_mutex);
        m_data[key] = v;
    }
    
    template<class T>
    T getData(const std::string& key,const T& def= T()){
        RWMutexType::ReadLock lock(m_mutex);
        auto it =  m_data.find(key);
        if(it==m_data.end()){
            return def;
        }
        boost::any v = it->second;
        lock.unlock();
        try{
            return boost::any_cast<T>(v);
        }catch(...){
        }
        return def;
    }

    void del(const std::string& key);
    bool has(const std::string& key);

    uint64_t getLastAccsessTime() const {return m_lastAccessTime;}
    void setLastAcccessTime(uint64_t v){m_lastAccessTime = v;}

    const std::string& getId() const {return m_id;}
    void setId(const std::string& id) {m_id = id;}



private:
    RWMutexType m_mutex;
    uint64_t m_lastAccessTime;
    std::string m_id;
    std::unordered_map<std::string,boost::any> m_data;
};

class SessionDataManager{
public:
    typedef RWMutex RWMutexType;

    void add(SessionData::ptr data);
    void del(const std::string& id);
    void del(std::vector<std::string>& ids);
    SessionData::ptr get(const std::string& id);
    void check(int64_t ts = 3600);
    void init();

private:
    RWMutexType m_mutex;
    std::unordered_map<std::string,SessionData::ptr> m_data;
};

typedef Singleton<SessionDataManager> SessionDataMgr;


}

}


#endif